#include "wifi_task.h"
#include <etimer.h>
#include <process.h>
#include <stdlib.h>
#include <string.h>
#include "Mqtt_task.h"
#include "device_manage.h"
#include "disp_task.h"
#include "http_task.h"
#include "key_task.h"
#include "net_api.h"
#include "time.h"
#include "tm1804.h"
#include "uart.h"
#include "voice_task.h"
#include "wifi.h"

PROCESS(WifiInit_Process, "WifiInit");
PROCESS(WifiCMD_Process, "WifiCMD");
PROCESS(Wifi_Status_Process, "WifiStatus");
PROCESS(Wifi_GetIPD_Process, "Wifi_GetIPD");
PROCESS(Wifi_SetNet_Process, "Wifi_SetNet");
PROCESS(Wifi_UnSetNet_Process, "Wifi_unSetNet");

extern uint8_t led;

enum {
  wifi_idle,
  wifi_gettime,
  wifi_getid,
  wifi_mqtt,
};

uint8_t wifidev_status = wifi_idle;

eWifiInfo wifi_info = Wifi_None;  // wifi网络状态

static bool is_gettime = false;  //时间是否获取标志
static bool is_play_netfailed_flag = false;
static bool is_play_netsuccceed_flag = false;


void set_wificmdval(sWifiCmd *WifiCmd, char *cmd, char *cmd_res,
                    struct process *notify) {
  WifiCmd->cmd = (uint8_t *)cmd;
  WifiCmd->res = (uint8_t *)cmd_res;
  WifiCmd->notify = notify;
}

PROCESS_THREAD(WifiCMD_Process, ev, data) {
  static uint16_t timeOut = 0;
  static uint8_t res = 0;
  static sWifiCmd WifiCmd;
  static struct etimer et;

  PROCESS_BEGIN();
  WifiCmd = *(sWifiCmd *)data;
  res = 0;
  timeOut = 1000;
  Wifi_ClearRecive();
  uart_send(WifiCmd.cmd, strlen((const char *)WifiCmd.cmd));
  etimer_set(&et, 50);
  PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  while (timeOut--) {
    if (Wifi_WaitRecive() == WIFI_REV_OK) {
      if (strstr((const char *)Net_IO.buf, (const char *)WifiCmd.res) != NULL) {
        Wifi_ClearRecive();
        res = 1;
        break;
      }
    }

    etimer_set(&et, 2);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }
  if (WifiCmd.notify != NULL) {
    process_post(WifiCmd.notify, PROCESS_EVENT_CMDEND, (process_data_t)&res);
  }

  PROCESS_END();
}

PROCESS_THREAD(WifiInit_Process, ev, data) {
  static uint8_t i = 0;
  static sWifiCmd cmd;
  static struct etimer et;
  static uint32_t tmp_time = 0;
  static uint8_t dev_flag = 0;
  static uint8_t count = 0;
  static sVoiceCmd voice;
  static uint8_t voice_value;

  PROCESS_BEGIN();

  led = Led_NoConnect;
  process_start(&DispLed_Process, (process_data_t)&led);

  etimer_set(&et, 100);
  wifi_info = Wifi_None;

  process_exit(&Wifi_GetIPD_Process);
  Wifi_Reset();
  etimer_set(&et, 400);
  PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  uart_send("+++", 3);
//  etimer_set(&et, 10);
//  PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
//  uart_send("+", 1);
//  etimer_set(&et, 10);
//  PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
//  uart_send("+", 1);
  etimer_set(&et, 100);
  PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
  uart_clear();
  uart_send((uint8_t *)"ATE1\r\n", strlen("ATE1\r\n"));
  if (cfg_data.Val.WifiFlag != Wifi_Init) {  //未配置wifi模块
    i = 3;
    set_wificmdval(&cmd, AT_CWMODE_DEF, AT_CWMODE_DEF_RES, &WifiInit_Process);
    wifisend_cmd(WifiCMD_Process, cmd, i);

    i = 3;
    set_wificmdval(&cmd, AT_CWAUTOCONN, AT_CWAUTOCONN_RES, &WifiInit_Process);
    wifisend_cmd(WifiCMD_Process, cmd, i);
	
	if(i>0){
		 cfg_data.Val.WifiFlag = Wifi_Init;
		 write_cfg(&cfg_data);
	}

  }

  i = 4;
  set_wificmdval(&cmd, AT_CIPDNS, AT_CIPDNS_RES, &WifiInit_Process);
  wifisend_cmd(WifiCMD_Process, cmd, i);

  dev_flag = 0;
  count = 0;
  wifidev_status = wifi_idle;
  
  printf("WifiInit_Process start\r\n");

  while (1) {
    if (wifi_info == Wifi_None || wifi_info == Wifi_Lost) {
      process_start(&Wifi_Status_Process, (process_data_t)&WifiInit_Process);
      wifidev_status = wifi_idle;
      count++;
      if (count == 50) {
        // HAL_NVIC_SystemReset();
        Wifi_Reset();
        etimer_set(&et, 500);
        PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
        uart_clear();
		if(!is_play_netfailed_flag && !is_play_netsuccceed_flag){
			is_play_netfailed_flag = true;
			voice_value = voice_netfailed;
			voice.cmd = voicecmd_playone;
			voice.value = (uint8_t *)&voice_value;
			process_start(&VoicePlay_Process, (process_data_t)&voice);
		}
		printf("Wifi_Reset\r\n");
      }
    } else if (wifi_info == Wifi_DisConn || wifi_info == Wifi_GoTIP) {
      process_exit(&Wifi_Status_Process);

      if (dev_flag == 0) {
        dev_flag = 1;
        if (cfg_data.Val.DeviceFlag == Device_Init) {
          //设备发现
          static uint8_t cmdbuf[128] = {0};
          sprintf((char *)cmdbuf, AT_CWSTARTDISCOVER, Product_ID, Product_ID,
                  cfg_data.Val.Device_id);
          i = 1;
          set_wificmdval(&cmd, (char *)cmdbuf, AT_CWSTARTDISCOVER_RES,
                         &WifiInit_Process);
          wifisend_cmd(WifiCMD_Process, cmd, i);
        }
      }
      if (is_gettime) {
        if (cfg_data.Val.DeviceFlag == Device_Init) {
          //启动mqtt
		  if(!is_play_netsuccceed_flag){
			  is_play_netsuccceed_flag = true;
			  voice_value = voice_netsuccess;
			  voice.cmd = voicecmd_playone;
			  voice.value = (uint8_t *)&voice_value;
			  process_start(&VoicePlay_Process, (process_data_t)&voice);
		  }
          led = Led_Connect;
          process_start(&DispLed_Process, (process_data_t)&led);
          uart_send((uint8_t *)"ATE0\r\n", strlen("ATE0\r\n"));
          uart_clear();
          netstatus = net_idle;
          wifidev_status = wifi_mqtt;
          process_start(&MqttInit_Process, NULL);
          process_exit(&WifiInit_Process);
          return PT_ENDED;
        } else {
          wifidev_status = wifi_getid;
          process_start(&HttpGetID_Process, (process_data_t)&WifiInit_Process);
          do {
            PROCESS_WAIT_EVENT();
          } while (ev != PROCESS_EVENT_CONTINUE);
          wifidev_status = wifi_idle;
          uint8_t res = *(uint8_t *)data;
          if (res == 1) {
            cfg_data.Val.DeviceFlag = Device_Init;
            write_cfg(&cfg_data);
          }
        }
      } else {
        netstatus = net_idle;
        wifidev_status = wifi_gettime;
        process_start(&HttpGetTime_Process, (process_data_t)&WifiInit_Process);
        tmp_time = HAL_GetTick();
        do {
          PROCESS_WAIT_EVENT();
        } while (ev != PROCESS_EVENT_CONTINUE &&
                 (HAL_GetTick() - tmp_time < 10000));
        wifidev_status = wifi_idle;
        uint8_t res = *(uint8_t *)data;
        if (res == 1) {
          is_gettime = true;
          i = 0;
        }
      }
    } else {
      i = 1;
      set_wificmdval(&cmd, AT_CIPCLOSE, AT_CIPCLOSE_RES, &WifiInit_Process);
      wifisend_cmd(WifiCMD_Process, cmd, i);
      process_start(&Wifi_Status_Process, (process_data_t)&WifiInit_Process);
    }
    etimer_set(&et, 500);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }

  PROCESS_END();
}

PROCESS_THREAD(Wifi_Status_Process, ev, data) {
  static uint8_t timeOut = 0;
  static struct etimer et;

  PROCESS_BEGIN();

  timeOut = 200;
  wifi_info = Wifi_None;

  Wifi_ClearRecive();
  uart_send((uint8_t *)AT_STATUS, strlen(AT_STATUS));

  while (timeOut--) {  //等待
    if (Wifi_WaitRecive() == WIFI_REV_OK) {
      if (strstr((const char *)Net_IO.buf, "STATUS:2") != NULL) {
        wifi_info = Wifi_GoTIP;
		printf("Wifi_GoTIP\r\n");
      } else if (strstr((const char *)Net_IO.buf, "STATUS:3") != NULL) {
        wifi_info = Wifi_Conn;
		printf("Wifi_Conn\r\n");
      } else if (strstr((const char *)Net_IO.buf, "STATUS:4") != NULL) {
        wifi_info = Wifi_DisConn;
		printf("Wifi_DisConn\r\n");
      } else if (strstr((const char *)Net_IO.buf, "STATUS:5") != NULL) {
        wifi_info = Wifi_Lost;
		printf("Wifi_Lost\r\n");
      } else {
        wifi_info = Wifi_None;
      }
    }
    etimer_set(&et, 3);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }

  process_post(data, PROCESS_EVENT_CONTINUE, NULL);

  PROCESS_END();
}

PROCESS_THREAD(Wifi_GetIPD_Process, ev, data) {
  static uint16_t byte = 0;
  static uint16_t count = 0;
  static char sByte[5];
  static char *ptrIPD;
  static struct etimer et;
  static uint16_t index = 0;
  static uint8_t flag = 0;
  static uint16_t offset = 0;

  PROCESS_BEGIN();

  byte = 0;
  count = 0;

  while (1) {
    index = 0;
    if (Wifi_WaitRecive() == WIFI_REV_OK) {  //如果接收完成
      while (1) {
        flag = 0;
        memset(sByte, 0, 5);
        ptrIPD = strstr((char *)&Net_IO.buf[index], "IPD,");  //搜索“IPD”头
        if (ptrIPD !=
            NULL) {  //如果没找到，可能是IPD头的延迟，还是需要等待一会，但不会超过设定的时间
          ptrIPD = strstr(ptrIPD, ",");
          ptrIPD++;  //找到','  ，然后偏移到下一个字符，代表数据长度的第一个数字
          count = 0;
          while (*ptrIPD != ':') {  //在','和':' 之间的都是数据长度的数据
            sByte[count++] = *ptrIPD++;
          }
          flag = 1;
          offset = ptrIPD - (char *)&Net_IO.buf[0];
        } else {
          Net_IO.dataLen = 0;
          Net_IO.dataLenPre = 0;
          memset(Net_IO.buf, 0, sizeof(Net_IO.buf));  //将后边的数据清空
          break;
        }
        if (flag == 1) {
          byte = atoi(sByte);  //将字符转为数值形式
          ptrIPD++;  //此时ptrIPD指针还指向':'，所以需要偏移到下个数据
          if (byte > (fifo_get.Depth - fifo_get.Counter)) {
            byte = fifo_get.Depth - fifo_get.Counter;
          }
          index = offset + 2 + byte;
          FIFO_Add(&fifo_get, ptrIPD, byte);
        }
      }
    }
    etimer_set(&et, 3);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }

  PROCESS_END();
}


PROCESS_THREAD(Wifi_SetNet_Process, ev, data) {
  static uint8_t i = 0;
  static sWifiCmd cmd;
  static uint32_t time;
  static uint8_t flag;
  static struct etimer et;
  static sVoiceCmd voice;
  static uint8_t voice_value;

  PROCESS_BEGIN();

  if (wifidev_status == wifi_gettime) {
    process_exit(&HttpGetTime_Process);
    i = 2;
    set_wificmdval(&cmd, AT_CIPCLOSE, AT_CIPCLOSE_RES, &Wifi_SetNet_Process);
    wifisend_cmd(WifiCMD_Process, cmd, i);
  } else if (wifidev_status == wifi_getid) {
    process_exit(&HttpGetID_Process);
    i = 2;
    set_wificmdval(&cmd, AT_CIPCLOSE, AT_CIPCLOSE_RES, &Wifi_SetNet_Process);
    wifisend_cmd(WifiCMD_Process, cmd, i);
  } else if (wifidev_status == wifi_mqtt) {
    process_exit(&MqttInit_Process);
    process_exit(&MqttConnect_Process);
    process_exit(&MqttSub_Process);
    process_exit(&MqttLoop_Process);
	etimer_set(&et, 1000);
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
	uart_send("+", 1);
	etimer_set(&et, 10);
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
	uart_send("+", 1);
	etimer_set(&et, 10);
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
	uart_send("+", 1);
	etimer_set(&et, 100);
	PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
    i = 2;
    set_wificmdval(&cmd, AT_CIPCLOSE, AT_CIPCLOSE_RES, &Wifi_SetNet_Process);
    wifisend_cmd(WifiCMD_Process, cmd, i);
  }
  process_exit(&WifiInit_Process);
  process_exit(&Wifi_GetIPD_Process);
  

  i = 3;
  set_wificmdval(&cmd, AT_RST, AT_RST_RES, &Wifi_SetNet_Process);
  wifisend_cmd(WifiCMD_Process, cmd, i);

  etimer_set(&et, 2000);
  PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));

  Wifi_ClearRecive();
  
  
  uart_send((uint8_t*)"AT+CWMODE=1\r\n", strlen("AT+CWMODE=1\r\n"));
  etimer_set(&et, 1000);
  
  i = 2;
  set_wificmdval(&cmd, AT_CWSTOPSMART, AT_CWSTOPSMART_RES,
                 &Wifi_SetNet_Process);
  wifisend_cmd(WifiCMD_Process, cmd, i);
  i = 1;
  set_wificmdval(&cmd, AT_CWSTARTSMART, AT_CWSTARTSMART_RES,
                 &Wifi_SetNet_Process);
  wifisend_cmd(WifiCMD_Process, cmd, i);

  time = HAL_GetTick();
  flag = 0;
  while ((HAL_GetTick() - time) < 120000) {
    if (Wifi_WaitRecive() == WIFI_REV_OK) {
      if (strstr((char *)Net_IO.buf, AT_CONNECT_RES)) {
        flag = 1;
        break;
      }
    }
    etimer_set(&et, 5);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
  }
  
  if (flag == 1) {
    time = ((HAL_GetTick() - time) / 1000) * 500 + 1000;
    etimer_set(&et, time);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
    voice_value = voice_setnetcomp;
    led = Led_SetNetOk;
    process_start(&DispLed_Process, (process_data_t)&led);

  } else {
    voice_value = voice_netfailed;
    led = Led_SetNetFailed;
    process_start(&DispLed_Process, (process_data_t)&led);
	process_start(&WifiInit_Process, NULL);  //退出配网后，重新wifi初始化
  }

  voice.cmd = voicecmd_playone;
  voice.value = (uint8_t *)&voice_value;
  process_start(&VoicePlay_Process, (process_data_t)&voice);

  setnet_finish();  //配网完成，回到功能界面
  PROCESS_END();
}

PROCESS_THREAD(Wifi_UnSetNet_Process, ev, data) {
  static uint8_t i = 0;
  static sWifiCmd cmd;
  static struct etimer et;

  PROCESS_BEGIN();

  process_exit(&Wifi_SetNet_Process);

  etimer_set(&et, 500);
  PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));

  i = 2;
  set_wificmdval(&cmd, AT_CWSTOPSMART, AT_CWSTOPSMART_RES,
                 &Wifi_UnSetNet_Process);
  wifisend_cmd(WifiCMD_Process, cmd, i);

  etimer_set(&et, 1000);
  PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));

  process_start(&WifiInit_Process, NULL);  //退出配网后，重新wifi初始化

  PROCESS_END();
}

void exit_wifi(void) {
  process_exit(&Wifi_GetIPD_Process);
  process_exit(&WifiInit_Process);
}
